package edu.stanford.bmir.protege.web.client.ui.ontology.stkos.mapper.common;

import com.google.gwt.core.shared.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.gwtext.client.widgets.tree.TreeNode;

import edu.stanford.bmir.protege.web.client.project.Project;
import edu.stanford.bmir.protege.web.client.rpc.data.EntityData;
import edu.stanford.bmir.protege.web.client.rpc.data.PropertyEntityData;
import edu.stanford.bmir.protege.web.client.rpc.data.PropertyType;
import edu.stanford.bmir.protege.web.client.rpc.data.ValueType;
import edu.stanford.bmir.protege.web.client.rpc.stkosutil.StkosUtilServiceManager;
import edu.stanford.bmir.protege.web.client.rpc.stkosutil.common.UtilConstants;
import edu.stanford.bmir.protege.web.client.rpc.stkosutil.common.UtilEntityType;
import edu.stanford.bmir.protege.web.client.ui.library.msgbox.MessageBox;
import edu.stanford.bmir.protege.web.client.ui.ontology.stkos.common.GWTExtUtil;
import edu.stanford.bmir.protege.web.client.ui.ontology.stkos.common.contextMenu.AbstractStkosTreeNodeMenuItem;
import edu.stanford.bmir.protege.web.client.ui.ontology.stkos.common.treepanel.AbstractStkosTreePanel;
import edu.stanford.bmir.protege.web.shared.PrimitiveType;
import edu.stanford.bmir.protege.web.shared.entity.OWLEntityData;

public abstract class AbstractStkosMapperMenuItem extends
		AbstractStkosTreeNodeMenuItem {
	
	protected static final String annotaionName = "rdfs:comment";

	protected AbstractStkosTreePanel treePanel;
	protected Project project;
	protected Project accordingProject;
	protected TreeNode treeNode;
	protected Integer mapperNumber;

	public AbstractStkosMapperMenuItem(AbstractStkosTreePanel treePanel,
			Project project, Project accordingProject, TreeNode treeNode,
			String text, String iconCls, boolean disabled) {
		super(text, iconCls, disabled);
		if (treePanel == null) {
			throw new NullPointerException("Argument treePanel Can't be null.");
		}
		if (project == null) {
			throw new NullPointerException("Argument project Can't be null.");
		}
		if (treeNode == null) {
			throw new NullPointerException("Argument treeNode Can't be null.");
		}
		if (project.getProjectId() == null
				|| project.getProjectId().getId() == null) {
			throw new NullPointerException("The projectId Can't be null.");
		}
		if (treeNode.getUserObject() == null) {
			throw new NullPointerException(
					"The treeNode`s userObject Can't be null.");
		}
		this.accordingProject = accordingProject;
		this.treePanel = treePanel;
		this.project = project;
		this.treeNode = treeNode;
	}

	protected Integer getMapperNumber() {
		try {
			mapperNumber = treePanel.getNodeMapperNumber(treeNode);
		} catch (Exception e) {
			GWT.log("Getting node mapper number error.", e);
		}
		return mapperNumber;
	}

	protected EntityData getEntityData() {
		EntityData entityData = null;
		try {
			if (treeNode.getUserObject() instanceof EntityData) {
				entityData = (EntityData) treeNode.getUserObject();
			} else if (treeNode.getUserObject() instanceof OWLEntityData) {
				OWLEntityData owlEntityData = (OWLEntityData) treeNode
						.getUserObject();
				entityData = new EntityData(owlEntityData.getEntity().getIRI()
						.toString(), owlEntityData.getBrowserText());
			}
		} catch (Exception e) {
			GWT.log("Getting tree node entityData error.", e);
		}
		return entityData;
	}

	protected UtilEntityType getEntityType() {
		UtilEntityType entityType = UtilEntityType.ANY_ENTITY;
		try {
			if (treeNode.getUserObject() instanceof EntityData) {
				EntityData entityData = (EntityData) treeNode.getUserObject();
				if (entityData instanceof PropertyEntityData) {
					PropertyEntityData propertyEntityData = (PropertyEntityData) entityData;
					PropertyType propertyType = propertyEntityData
							.getPropertyType();
					if (propertyType != null) {
						switch (propertyType) {
						case OBJECT:
							entityType = UtilEntityType.OBJECT_PROPERTY;
							break;
						case DATATYPE:
							entityType = UtilEntityType.DATATYPE;
							break;
						case ANNOTATION:
							entityType = UtilEntityType.ANNOTATION_PROPERTY;
							break;
						default:
							break;
						}
					}
				} else if (entityData.getValueType() == ValueType.Cls) {
					entityType = UtilEntityType.CLASS;
				} else if (entityData.getValueType() == ValueType.Instance) {
					entityType = UtilEntityType.NAMED_INDIVIDUAL;
				} else {
				}
			} else if (treeNode.getUserObject() instanceof OWLEntityData) {
				OWLEntityData owlEntityData = (OWLEntityData) treeNode
						.getUserObject();
				PrimitiveType type = owlEntityData.getType();
				if (type != null) {
					switch (type) {
					case CLASS:
						entityType = UtilEntityType.CLASS;
						break;
					case ANNOTATION_PROPERTY:
						entityType = UtilEntityType.ANNOTATION_PROPERTY;
						break;
					case DATA_TYPE:
						entityType = UtilEntityType.DATATYPE;
						break;
					case OBJECT_PROPERTY:
						entityType = UtilEntityType.OBJECT_PROPERTY;
						break;
					case NAMED_INDIVIDUAL:
						entityType = UtilEntityType.NAMED_INDIVIDUAL;
						break;
					default:
						break;
					}
				}
			}
		} catch (Exception e) {
			GWT.log("Getting tree node entityType error.", e);
		}
		return entityType;
	}
	
	protected void refreshTreeNode() {
		treePanel.refreshTreeNode(treeNode);
	}
	
	
	protected void deleteMapperNumber() {
		if (mapperNumber == null) {
			treePanel.refreshTreeNode(treeNode);
			return;
		}
		if (accordingProject == null || accordingProject.getProjectId() == null
				|| accordingProject.getProjectId().getId() == null) {
			MessageBox.showAlert("温馨提示", "请选择一个参考本体!");
			return;
		}
		String projectName = project.getProjectId().getId();
		String entityName = treeNode.getId();
		UtilEntityType entityType = getEntityType();
		String annotaionValuePattern = "mappingNo:*; refProjectName:*; refProjectID:"
				+ accordingProject.getProjectId().getId();
		AsyncCallback<Integer> callback = new AsyncCallback<Integer>() {

			@Override
			public void onFailure(Throwable caught) {
				MessageBox.showErrorMessage("删除映射号失败", caught);
			}

			@Override
			public void onSuccess(Integer result) {
				MessageBox.showMessage("温馨提示", "删除映射号成功!");
				refreshTreeNode();
			}
		};

		StkosUtilServiceManager.getInstance().removeAnnotationValue(
				projectName, entityName, entityType, annotaionName,
				annotaionValuePattern, callback);
	}

	protected String getAnnotaionValuePattern() {
		String annotaionValuePattern = UtilConstants.FLAG_MAPPING_NO + ":{0}; "
				+ UtilConstants.FLAG_REF_PROJECT_DISPLAY_NAME + ":{1}; "
				+ UtilConstants.FLAG_REF_PROJECT_ID + ":{2}";
		try {
			String mappingNo = (getMapperNumber() == null || mapperNumber < 0) ? "*"
					: String.valueOf(mapperNumber);
			String refProjectName = accordingProject.getDisplayName();
			String refProjectID = accordingProject.getProjectId().getId();

			annotaionValuePattern = GWTExtUtil.stringFormat(annotaionValuePattern, mappingNo,
					refProjectName, refProjectID);
		} catch (Exception e) {
			GWT.log("Getting entity annotaionValuePattern error.", e);
		}
		return annotaionValuePattern;
	}
}
